home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
BMUG Revelations
/
BMUG Revelations.toast
/
Programming
/
Programming Languages
/
Yerk 3.64
/
Supplement
/
Unsupported
/
Optionals
/
SQwave
< prev
next >
Wrap
Text File
|
1986-02-08
|
4KB
|
141 lines
\ Square Wave sound generation class
\ written 7/3/85 by John Papiewski
\ v 1.1 7/6/85 added Octave array, Fixed first-note bug
\ added no-wait code July 11, 1985
\ musr first load: Struct1
:Class SQWave <Super Warray
12 bytes name \ driver name
12 bytes header \ fields for internal use
Var IOComp \ i/o completion ptr
Int IOResult \ return code
Var IONamePtr \ name of drvr
Int vref
Int IORefNum
Int csCode \ 26
Int csP1 \ 28
Int csP2 \ 30
Var IOBuffer
Var IOReq
Var IOAct
6 bytes junk2 \ posMode, offset - block devices only
var Proc
24 Warray Octave \ This array can be used by your program to make music.
\ the 0th element is C below Mid-C, 1st is D-flat, etc.
\ This array gets initialized by Setnotes method (see below)
35 3 * Warray Tones \ this array holds the notes to be played. The number of
\ elements needed = (notes + 2) x 3, so just change the
\ "35" to some other value for your program.
\ Pitch of note (hz) = 783360/count
\ loudness of note = 0-255
\ duration of note = 0-255 ticks @ 60/second
:M SQclear:
clear: Tones
;M
:M SetCnt: { Cnt Cindex -- }
Cnt Cindex 3 * 1 + to: Tones
;M
:M Setloud: { Loud Lindex -- }
Loud Lindex 3 * 2 + To: Tones
;M
:M SetSDur: { Dur Dindex -- }
Dur Dindex 3 * 3 + To: Tones
;M
:M SetNotes:
5935 0 To: Octave 5564 1 To: Octave 5275 2 To: Octave 4945 3 To: Octave
4748 4 To: Octave 4451 5 To: Octave 4172 6 To: Octave 3956 7 To: Octave
3709 8 To: Octave 3561 9 To: Octave 3391 10 To: Octave 3165 11 To: Octave
2967 12 To: Octave 2782 13 To: Octave 2638 14 To: Octave 2473 15 To: Octave
2374 16 To: Octave 2225 17 To: Octave 2086 18 To: Octave 1978 19 To: Octave
1855 20 To: Octave 1780 21 To: Octave 1696 22 To: Octave 1583 23 To: Octave
;M
:M PutNote: { Tone Dest -- }
Tone At: Octave Dest SetCnt: Self
;M
\ ( addr len -- ) name the driver
:M NAME: ^base 50 erase addr: name >str255
put: ioNamePtr ;M
:M OPEN: addr: header 0 (open) ;M
:M CLOSE: addr: header (close) ;M
\ ( addr len -- ) read n bytes via the driver
:M READ: { addr len -- fcode } addr: header len addr (read) ;M
\ no-wait read requires a completion PROC
:M READNW: { theWord addr len -- fcode }
addr +base put: IOBuffer theWord +base put: IOComp
len put: IOReq addr: header $ a402 (fdos) ;M
\ no-wait write requires a completion PROC
:M WRITENW: { theWord addr len -- fcode }
addr +base put: IOBuffer theWord +base put: IOComp
len put: IOReq addr: header $ a403 (fdos) ;M
\ write n bytes via the driver
:M WRITE: { addr len -- fcode } addr: header len addr (write) ;M
\ return actual count of bytes read
:M BYTESREAD: get: IOAct ;M
\ leave the current IOResult value
:M RESULT: get: IOResult ;M
:M Dosq: { Notes -- }
-4 put: IORefnum put: IOComp 2 Notes 1 + 6 * + put: IOreq
Abs: Tones 4 + Put: IOBuffer
" .Sound" name: SELF open: Self
-1 0 To: Tones ixaddr: Tones
2 Notes 2 + 6 * + write: Self
drop
;M
:M NWDosq: { Notes Proc -- } \ No-wait (asynchronous) version
-4 put: IORefnum put: IOComp 2 Notes 1 + 6 * + put: IOreq
Abs: Tones 4 + Put: IOBuffer
" .Sound" name: SELF open: Self
-1 0 To: Tones
Proc ixaddr: Tones 2 Notes 2 + 6 * + writeNW: Self
drop
;M
;Class
\ Here's the example:
\ The following Procedure executes on an interrupt from the Mac
\ When I/O is done, when you use the no-wait write.
\ You can put other stuff in the proc definition to suit your application
0 value DoneSwitch
:Proc Done 1 -> DoneSwitch ;Proc
cr cr
." Square Wave Demonstration"
1 SqWave Tune
SetNotes: Tune
SQclear: Tune
: PlayTune
12 0 Do
i dup PutNote: Tune
128 i SetLoud: Tune 26 i SetSdur: Tune
Loop
;
Playtune
12 ' Done NWDosq: Tune
cr
." Waiting for finish"
: Waitdone
Begin DoneSwitch Until
;
Waitdone
SQclear: Tune
1000 0 Setcnt: Tune
128 0 SetLoud: Tune
120 0 SetSdur: Tune
1 ' Done NWDosq: Tune